﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Collections;
using System.Xml.Linq;

[assembly:CLSCompliant(true)]
namespace ArmoryData
{
    public static class Connector
    {
        static int tryCount = 0;
        /// <summary>
        /// Downloads the source of the uri
        /// </summary>
        /// <param name="uri">The url to get the source from</param>
        /// <param name="proxy">The proxy.</param>
        /// <returns>The source of the uri</returns>
        public static string GetHtml(Uri uri, IWebProxy proxy=null)
        {
            StreamReader reader = new StreamReader(GetStream(uri, proxy));
            string str = "";
            while (!reader.EndOfStream)
            {
                str += reader.ReadLine() + Environment.NewLine;
            };
            reader.Close();
            tryCount = 0;
            return str;
        }

        public static Stream GetStream(Uri uri, IWebProxy proxy=null)
        {
            try
            {
                tryCount++;
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
                request.UserAgent = "Firefox/2.";
                request.Proxy = proxy;
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                return response.GetResponseStream();
            }
            catch (WebException ex)
            {
                // Workaround for Windows Mobile 6 bug
                if (ex.Message.Contains("transport connection") && tryCount <= 3)
                    return GetStream(uri);
                else
                    throw ex;
            }
        }

        /// <summary>
        /// Searches the Armory for the specified query
        /// </summary>
        /// <param name="armoryUrl">The url of the armory</param>
        /// <param name="query">The query to search for</param>
        /// <param name="searchType">The type of character to return</param>
        /// <returns>A list of search results</returns>
        public static List<Dictionary<string, string>> GetSearchResults(Uri armoryUrl, string query, string searchType)
        {
            List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
            Uri url = new Uri(string.Format("{0}/search.xml?searchQuery={1}&searchType={2}&rhtml=n", armoryUrl, query, searchType));
            
            // Parse the search results and add them to the array
            IEnumerable<XElement> data = XElement.Parse(GetHtml(url)).Descendants(searchType.Replace("s", "").Replace("team", "Team"));
            foreach (XElement e in data)
            {
                Dictionary<string, string> result;
                switch (searchType)
                {
                    case "characters":
                        result = new Dictionary<string,string>();
                        result.Add("Name", e.Attribute("name").Value);
                        result.Add("Level", e.Attribute("level").Value);
                        result.Add("Race", e.Attribute("race").Value);
                        result.Add("Class", e.Attribute("class").Value);
                        result.Add("Faction", e.Attribute("faction").Value);
                        result.Add("Guild", e.Attribute("guild").Value);
                        result.Add("Realm", e.Attribute("realm").Value);
                        result.Add("Battlegroup", e.Attribute("battleGroup").Value);
                        break;

                    case "arenateams":
                        result = new Dictionary<string, string>();
                        result.Add("Name", e.Attribute("name").Value);
                        result.Add("Realm", e.Attribute("realm").Value);
                        result.Add("Battlegroup", e.Attribute("battleGroup").Value);
                        result.Add("Size", string.Format("{0}v{0}", e.Attribute("size").Value));
                        result.Add("Faction", e.Attribute("faction").Value);
                        break;
                    case "guilds":
                        result = new Dictionary<string,string>();
                        result.Add("Name", e.Attribute("name").Value);
                        result.Add("Realm", e.Attribute("realm").Value);
                        result.Add("Battlegroup", e.Attribute("battleGroup").Value);
                        result.Add("Faction", e.Attribute("faction").Value);
                        break;
                    default:
                        throw new ArgumentOutOfRangeException("searchType");
                }

                results.Add(result);
            }

            // Check for results
            if (results.Count <= 0)
            {
                Dictionary<string, string> temp = new Dictionary<string, string>();
                temp.Add("Name", "No results...");
                results.Add(temp);
            }
            return results;
        }
    }
}
